<template>
  <!-- 消息通知 -->
  <div class="msg-wrapper">
    <div class="msg-header">
      <div class="sumary-title">
        <a-badge
          class="title-text"
          :count="totalCount"
          :number-style="{ backgroundColor: '#F59A23' }"
          :offset="[6, 0]"
          :overflow-count="30"
        >
          <span>消息通知</span>
        </a-badge>
      </div>
      <div class="all-btn">
        <div
          class="read-all base-btn"
          @click="readAllMessage"
        >
          <span>全部已读</span>
        </div>
        <div
          class="look-all base-btn"
          @click="lookAllMessage"
        >
          <span class="all-btn-text">查看全部</span> <a-icon
            class="all-btn-symbol"
            type="right"
          />
        </div>
      </div>
    </div>
    <div class="msg-body">
      <a-timeline v-if="messageList.length > 0">
        <a-timeline-item
          v-for="item in messageList"
          :key="item.id"
          :color="item.hasRead ? 'gray' : 'red'"
        >
          <div class="msg-preinfo">
            <span class="date-info">{{ filterTime(item.createTime) }}</span>
            <div
              v-if="!item.hasRead"
              @click="readSingleMessage(item)"
            >
              <a-icon
                v-if="item.isReading"
                type="loading"
              />
              <img
                v-else
                class="read-icon base-btn"
                src="~@/assets/indexPage/read.png"
                alt=""
              >
            </div>
          </div>
          <div
            class="msg-info"
            :class="{ 'readed-msg': item.hasRead }"
            @click="toMessageDetail(item)"
          >
            <div class="msg-info-header">
              <span class="msg-info-title">{{ item.title }}</span>
              <a-tag
                class="ml12"
                :color="item.messageType | typeColor"
              >
                {{ item.messageType | newsTypeFilter }}
              </a-tag>
            </div>
            <Ellipsis
              :length="60"
              :title="item.content"
              class="msg-info-content"
            >
              {{ item.messageType == 4 ? resolveMessage(item.content).labelText : item.content }}
            </Ellipsis>
          </div>
        </a-timeline-item>
      </a-timeline>
      <EmptyWrapper v-else>
        <template v-slot:img>
          <img
            class="msg-empty-img"
            src="~@/assets/indexPage/msg-empty.png"
            alt=""
          >
        </template>
        <span>暂无消息</span>
      </EmptyWrapper>
      <div class="extra-tip">
        <span v-if="messageList.length > 0 && messageList.length <= 30">没有更多消息了</span>
        <span v-if="messageList.length > 30">更多消息请点击查看全部</span>
      </div>
    </div>
  </div>
</template>

<script>
import Ellipsis from '@/components/Ellipsis'
import messageBase from '@/views/matters/message/baseconfig.js'
import EmptyWrapper from './EmptyWrapper.vue'
import { timeline } from 'ant-design-vue'
import { getMessageList, updateMessageRead, updateAllMessageRead } from '@/api/indexPage'
import { getTimeGap } from '@/utils/util'

export default {
  name: 'MsgNotify',
  components: {
    EmptyWrapper,
    [timeline.name]: timeline, // "ATimeline"
    [timeline.Item.name]: timeline.Item, // "ATimelineItem"
    Ellipsis
  },
  filters: {
    newsTypeFilter(type) {
      return messageBase.newsTypeMap[type] && messageBase.newsTypeMap[type].text
    },
    typeColor(type) {
      return messageBase.newsTypeMap[type] && messageBase.newsTypeMap[type].color
    }
  },
  data() {
    return {
      totalCount: 0,
      messageList: [] // 消息通知列表
    }
  },
  created() {
    this.getMessageListReq()
    this.initTimer()
  },
  methods: {
    resolveMessage(msg) {
      if (!msg)
        return {
          originText: msg,
          keyText: '',
          labelText: msg
        }
      let key = ''
      ;(msg.replace &&
        msg.replace(/^\[(.+?)\]/g, function (...args) {
          key = args[0]
        })) ||
        ''
      return {
        originText: msg,
        keyText: key.substring(1, key.length - 1),
        labelText: (msg.replace && msg.replace(key, '')) || ''
      }
    },
    toMessageDetail(data) {
      this.$router.push({
        path: '/matters/news/read',
        query: {
          needJump: JSON.stringify({
            createTime: data.createTime,
            text: {
              ...data,
              id: data.messageSendId
            }
          })
        }
      })
    },
    filterTime(val) {
      return getTimeGap(val)
    },
    /**
     * 查看所有消息
     */
    lookAllMessage() {
      this.$router.push({
        path: '/matters/news/toread'
      })
    },
    /**
     * 将所有消息标记已读
     */
    readAllMessage() {
      if (!this.totalCount) {
        this.$message.warning('没有未读消息')
        return
      }
      this.$confirm({
        content: '请确认是否将所有消息标记为已读？',
        onOk: async () => {
          await updateAllMessageRead({
            receiverId: this.messageList[0].receiversId
          })
          this.getMessageListReq()
          return
        }
      })
    },
    /**
     * 将单个消息标记为已读
     * @param {Object} data
     */
    async readSingleMessage(data) {
      try {
        if (data.isReading) return
        this.$set(data, 'isReading', true)
        const { messageSendId, receiversId } = data
        const params = {
          sendId: messageSendId,
          receiversId
        }
        await updateMessageRead(params)
        data.hasRead = true // 接口调用成功后，将该消息置为已读
      } catch (e) {
        console.error(e)
      }
      this.$set(data, 'isReading', false)
    },
    /**
     * 初始化timer，轮询获取消息通知
     */
    initTimer() {
      if (this.messageTimer) {
        clearTimeout(this.messageTimer)
        this.messageTimer = null
      }
      this.messageTimer = setTimeout(() => {
        this.getMessageListReq()
        this.initTimer()
      }, 1000 * 600)
      this.$once('hook:beforeDestroy', () => {
        clearTimeout(this.messageTimer)
      })
    },
    /**
     * 获取消息通知的列表
     */
    async getMessageListReq() {
      try {
        const params = {
          pageNum: 1,
          pageSize: 31,
          param: {}
        }
        const res = await getMessageList(params)
        this.messageList = res.data?.list || []
        this.totalCount = this.messageList.filter((item) => !item.hasRead).length
      } catch (e) {
        console.log(e)
      }
    }
  }
}
</script>

<style lang="less" scoped>
.msg-wrapper {
  max-height: 442px;
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  .msg-header {
    padding: 20px 20px 6px 20px;
    border-bottom: 1px solid #ffffff;
    box-shadow: 3px 2px 20px 0px rgba(24, 48, 60, 0.1);
    display: flex;
    justify-content: space-between;
    align-items: center;
    .sumary-title {
      color: #161616;
      position: relative;
      font-weight: bolder;
      width: fit-content;
      .title-text {
        font-size: 18px;
        z-index: 3;
      }
      &::after {
        z-index: 2;
        display: block;
        content: '';
        width: 110%;
        height: 10px;
        background: #cdf1f9;
        position: absolute;
        bottom: 0;
      }
    }
    .all-btn {
      line-height: 24px;
      padding-left: 30px;
      flex: auto;
      display: flex;
      align-items: center;
      justify-content: space-between;
      font-size: 14px;
      color: #0289ca;
      .all-btn-text {
        margin-right: 4px;
      }
      .all-btn-symbol {
        color: #666666;
      }
    }
  }
  .msg-body {
    max-height: calc(var(--heightVh) * 0.56);
    overflow-y: scroll;
    margin-right: -25px;
    padding: 20px;
  }
  .msg-empty-img {
    width: 232px;
    height: 160px;
  }
  .msg-preinfo {
    display: flex;
    justify-content: space-between;
    align-items: center;
    .date-info {
      font-size: 12px;
      color: #999999;
    }
    .read-icon {
      width: 16px;
      height: 16px;
    }
  }
  .readed-msg {
    background: #fafafa !important;
  }
  .msg-info {
    display: flex;
    flex-direction: column;
    background: #f1f6f9;
    padding: 16px;
    border-radius: 2px;
    .msg-info-header {
      padding-bottom: 12px;
    }
    .msg-info-title {
      font-size: 16px;
      font-weight: bolder;
      color: #333333;
      line-height: 16px;
    }
    .msg-info-content {
      font-size: 12px;
      color: #888888;
      line-height: 18px;
    }
  }
  .extra-tip {
    text-align: center;
  }
}
</style>